<template>
  <div class="version-management-page">
    <div class="page-wrapper">
      <section class="sidebar" :class="{ 'is-collapsed': isCollapsed }">
        <header class="sidebar-header">
          <h3>版本列表</h3>
          <el-button text size="small" class="collapse-btn" @click="toggleCollapse">
            <el-icon><DArrowLeft v-if="!isCollapsed" /><DArrowRight v-else /></el-icon>
          </el-button>
        </header>
        <div class="sidebar-content" v-show="!isCollapsed">
          <el-input
            v-model="versionSearch"
            :prefix-icon="Search"
            placeholder="搜索版本名称或版本号"
            clearable
            size="small"
            class="version-search-input"
          />
          <div class="version-list-wrapper">
            <el-skeleton v-if="versionLoading" :rows="6" animated />
          <el-scrollbar v-else>
            <div v-if="filteredVersions.length" class="version-list">
              <article
                v-for="item in filteredVersions"
                :key="item.id"
                :class="['version-card', { 'is-active': item.id === selectedVersionId }]"
                @click="handleSelectVersion(item.id)"
              >
                <header class="version-card-header">
                  <div class="version-name-wrapper">
                    <h3 class="version-name" :title="item.name || '未命名版本'">
                      {{ item.name || '未命名版本' }}
                    </h3>
                    <el-icon
                      v-if="item.is_pinned"
                      class="pinned-icon"
                      :title="'已置顶'"
                    >
                      <StarFilled />
                    </el-icon>
                  </div>
                  <div class="header-actions">
                    <div class="status-trigger" @click.stop>
                      <el-dropdown
                        v-if="canTransition"
                        trigger="click"
                        placement="bottom-end"
                        @command="(transition: any) => openTransitionDialog(item.id, transition)"
                        @visible-change="(visible: any) => visible && loadVersionTransitionData(item.id)"
                      >
                        <span class="status-dropdown">
                          <VersionStatusTag :status="castVersionStatus(item.status)" size="small" />
                          <el-icon class="status-dropdown-icon"><ArrowDown /></el-icon>
                        </span>
                        <template #dropdown>
                          <el-dropdown-menu>
                            <el-dropdown-item
                              v-if="transitionLoadingMap[item.id]"
                              disabled
                            >
                              加载中...
                            </el-dropdown-item>
                            <template v-else>
                              <el-dropdown-item
                                v-for="transition in allowedTransitionsMap[item.id] || []"
                                :key="transition.to_status"
                                :command="transition"
                              >
                                {{ transition.name }}
                              </el-dropdown-item>
                              <el-dropdown-item
                                v-if="!(allowedTransitionsMap[item.id]?.length)"
                                disabled
                              >
                                暂无可执行操作
                              </el-dropdown-item>
                            </template>
                          </el-dropdown-menu>
                        </template>
                      </el-dropdown>
                      <VersionStatusTag
                        v-else
                        :status="castVersionStatus(item.status)"
                        size="small"
                      />
                    </div>
                    <el-dropdown trigger="click" placement="bottom-end" @click.stop>
                      <el-button
                        type="text"
                        size="small"
                        class="action-button"
                        :icon="MoreFilled"
                      />
                      <template #dropdown>
                        <el-dropdown-menu>
                          <el-dropdown-item @click="handleViewVersion(item.id)">
                            <el-icon><View /></el-icon>
                            查看详情
                          </el-dropdown-item>
                          <el-dropdown-item
                            v-if="canEdit"
                            @click="handleEditVersion(item.id)"
                          >
                            <el-icon><Edit /></el-icon>
                            编辑版本
                          </el-dropdown-item>
                          <el-dropdown-item
                            v-if="canEdit"
                            @click="handleTogglePin(item)"
                          >
                            <el-icon><StarFilled v-if="item.is_pinned" /><Star v-else /></el-icon>
                            {{ item.is_pinned ? '取消置顶' : '置顶' }}
                          </el-dropdown-item>
                          <el-dropdown-item
                            v-if="canDelete"
                            @click="handleDeleteVersion(item)"
                            divided
                          >
                            <el-icon><Delete /></el-icon>
                            删除版本
                          </el-dropdown-item>
                        </el-dropdown-menu>
                      </template>
                    </el-dropdown>
                  </div>
                </header>
                <div class="version-meta">
                  <span class="version-number" :title="item.version_number || '无版本号'">
                    {{ item.version_number || '无版本号' }}
                  </span>
                  <span class="project-name" :title="item.project_name || '未关联项目'">
                    {{ item.project_name || '未关联项目' }}
                  </span>
                </div>
                <ul class="version-stats">
                  <li class="stat-item">
                    <span class="stat-label">需求</span>
                    <span class="stat-value">
                      {{ item.requirement_stats?.completed ?? 0 }}/{{ item.requirement_stats?.total ?? 0 }}
                    </span>
                  </li>
                  <li class="stat-item">
                    <span class="stat-label">任务</span>
                    <span class="stat-value">
                      {{ item.task_stats?.completed ?? 0 }}/{{ item.task_stats?.total ?? 0 }}
                    </span>
                  </li>
                  <li class="stat-item">
                    <span class="stat-label">缺陷</span>
                    <span class="stat-value">
                      {{ item.defect_stats?.completed ?? 0 }}/{{ item.defect_stats?.total ?? 0 }}
                    </span>
                  </li>
                </ul>
                <div class="overall-progress">
                  <span class="overall-label">整体进度</span>
                <el-progress
                    class="overall-progress-bar"
                    :percentage="calcOverallPercent(item)"
                  :stroke-width="6"
                  :show-text="false"
                  status="success"
                />
                  <span class="overall-percent">{{ Math.round(calcOverallPercent(item)) }}%</span>
              </div>
                <div class="overall-detail">
                  <span>需求 {{ Math.round(calcPercent(item.requirement_stats)) }}%</span>
                  <span>任务 {{ Math.round(calcPercent(item.task_stats)) }}%</span>
                  <span>缺陷 {{ Math.round(calcPercent(item.defect_stats)) }}%</span>
                </div>
                <footer class="version-footer">
                  <span class="footer-label">计划发布</span>
                  <span class="footer-value">
                    {{ formatPlannedDate(item.planned_release_date) || '未设置' }}
                  </span>
                </footer>
              </article>
            </div>
            <el-empty v-else description="暂无版本数据" :image-size="120" />
          </el-scrollbar>
          </div>
        </div>
      </section>

      <section class="main-panel">
        <header class="main-header">
          <div class="main-title">
            <h2 v-if="versionDetail" class="title-text">{{ versionDetail.name }}</h2>
            <h2 v-else class="title-text">版本详情</h2>
            <div v-if="versionDetail" class="title-tags">
              <VersionStatusTag :status="castVersionStatus(versionDetail.status)" size="small" />
              <el-tag size="small" effect="plain">{{ versionDetail.version_number }}</el-tag>
              <el-tag
                v-if="versionDetail.project_name"
                size="small"
                type="info"
                effect="plain"
              >
                {{ versionDetail.project_name }}
              </el-tag>
              <span class="title-meta-item">
                计划发布时间：{{ formatPlannedDate(versionDetail.planned_release_date) || '未设置' }}
              </span>
              <span class="title-meta-item">
                计划工时：{{ versionDetail.planned_work_hours ? `${versionDetail.planned_work_hours}h` : '—' }}
              </span>
            </div>
          </div>
          <div class="main-actions">
          <el-button type="primary" plain @click="goToPlanning">
            规划需求
          </el-button>
            <el-button type="primary" link :loading="versionLoading" @click="refreshVersions">
              <el-icon><RefreshRight /></el-icon>
              刷新
            </el-button>
          </div>
        </header>

        <!-- 初始加载状态 -->
        <PageLoading 
          v-if="initialLoading"
          :title="isRefreshing ? '正在刷新版本数据' : '正在加载版本数据'"
          :subtitle="isRefreshing ? '请稍候，正在更新数据...' : '请稍候，正在为您准备数据...'"
        />
        <el-empty
          v-else-if="!selectedVersionId && !versionLoading"
          description="请在左侧选择要查看的版本"
          :image-size="160"
        />

        <div
          v-else
          class="version-content"
          v-loading="workItemsLoading"
        >
          <div class="work-items-card">
            <header class="work-items-header">
              <div class="tabs-wrapper">
                <el-tabs v-model="activeType" class="work-item-tabs">
                  <el-tab-pane label="需求" name="requirement">
                    <template #label>
                      <span class="tab-label">
                        <span class="tab-name">需求</span>
                        <el-badge :value="workItemCounts.requirement" :max="99" class="tab-badge" />
                      </span>
                    </template>
                  </el-tab-pane>
                  <el-tab-pane label="任务" name="task">
                    <template #label>
                      <span class="tab-label">
                        <span class="tab-name">任务</span>
                        <el-badge :value="workItemCounts.task" :max="99" class="tab-badge" />
                      </span>
                    </template>
                  </el-tab-pane>
                  <el-tab-pane label="缺陷" name="defect">
                    <template #label>
                      <span class="tab-label">
                        <span class="tab-name">缺陷</span>
                        <el-badge :value="workItemCounts.defect" :max="99" class="tab-badge" />
                      </span>
                    </template>
                  </el-tab-pane>
                </el-tabs>
              </div>
            </header>

            <!-- 动态组件：复用现有的列表组件 -->
            <div class="work-items-content">
              <transition name="fade-slide" mode="out-in">
                <component
                  :is="activeListComponent"
                  :key="`${activeType}-${selectedVersionId}`"
                  v-bind="activeListProps as any"
                  @open-detail="handleOpenDetail"
                  @update-status="handleUpdateStatus"
                  @update-priority="handleUpdatePriority"
                  @update-severity="handleUpdateSeverity"
                  @update-assignee="handleUpdateAssignee"
                  @delete="handleDelete"
                  @refresh="handleRefresh"
                  @page-change="handlePageChange"
                  @page-size-change="handlePageSizeChange"
                  @select-change="handleSelectChange"
                  @split-task="handleSplitTask"
                />
              </transition>
            </div>
          </div>
        </div>
      </section>
    </div>
    
    <!-- 分配负责人对话框 -->
    <el-dialog
      v-model="assignDialogVisible"
      title="分配负责人"
      width="500px"
      :close-on-click-modal="false"
    >
      <div v-if="currentAssignItem">
        <p style="margin-bottom: 16px; color: #606266;">
          <span style="margin-right: 8px;">{{ typeMetaMap[currentAssignItem.type as WorkItemType]?.label || '工作项' }}：</span>
          <strong>{{ currentAssignItem.title }}</strong>
        </p>
        <el-select
          v-model="selectedAssigneeId"
          placeholder="请选择负责人"
          filterable
          clearable
          style="width: 100%"
          size="default"
        >
          <el-option label="未分配" value="" />
          <el-option
            v-for="user in users"
            :key="user.id"
            :label="user.name"
            :value="user.id"
          >
            <div style="display: flex; align-items: center; gap: 8px;">
              <el-avatar :size="24" :src="user.avatar">
                {{ (user.name || '').charAt(0).toUpperCase() }}
              </el-avatar>
              <span>{{ user.name }}</span>
            </div>
          </el-option>
        </el-select>
      </div>
      <template #footer>
        <el-button @click="assignDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmAssign" :loading="assignLoading">确定</el-button>
      </template>
    </el-dialog>

    <!-- 任务创建对话框（用于任务拆分） -->
    <TaskCreateDialog
      v-model="taskSplitDialogVisible"
      :project-id="taskSplitItem?.projectId || ''"
      :default-requirement-id="taskSplitItem?.type === 'requirement' ? taskSplitItem.id : ''"
      :default-version-ids="selectedVersionId ? [selectedVersionId] : []"
      @success="handleTaskCreated"
    />
    <VersionTransitionDialog
      v-model="transitionDialogVisible"
      :version-id="currentTransitionVersionId"
      :transition="currentTransition"
      :completion-data="currentCompletionData"
      @success="handleTransitionSuccess"
    />
    <VersionDetailDialog
      v-model="detailDialogVisible"
      :version-id="currentVersionId"
      @edit="handleEditFromDetail"
    />
    <VersionCreateDialog
      v-model="editDialogVisible"
      :version-id="currentVersionId"
      @updated="handleVersionUpdated"
    />
    
    <!-- 需求详情对话框 -->
    <RequirementDetail
      v-if="requirementsStore.activeRequirementId && requirementsStore.activeRequirement"
      :visible="requirementsStore.detailVisible && !!requirementsStore.activeRequirementId && !!requirementsStore.activeRequirement"
      :requirement="requirementsStore.activeRequirement"
      :projects="requirementsStore.projects"
      :users="requirementsStore.users"
      :status-options="requirementsStore.statusOptions"
      :priority-options="requirementsStore.priorityOptions"
      :common-tags="requirementsStore.tagOptions"
      :current-user-id="currentUserId"
      :version-options="versionOptions"
      @update:visible="handleRequirementDetailVisibleChange"
    />
    
    <!-- 任务详情对话框 -->
    <TaskViewDialog
      v-model="taskViewDialogVisible"
      :task-id="selectedTaskId"
    />
    
    <!-- 缺陷详情对话框（已删除，待实现新组件） -->
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, reactive, ref, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, RefreshRight, ArrowDown, MoreFilled, View, Edit, Delete, StarFilled, Star, DArrowLeft, DArrowRight } from '@element-plus/icons-vue'
import VersionStatusTag from '@/components/version/VersionStatusTag.vue'
import VersionTransitionDialog from '@/components/version/VersionTransitionDialog.vue'
import VersionDetailDialog from '@/components/version/VersionDetailDialog.vue'
import VersionCreateDialog from '@/components/version/VersionCreateDialog.vue'
import RequirementDetail from '@/views/requirements/components/RequirementDetail.vue'
import TaskViewDialog from '@/components/task/TaskViewDialog.vue'
import TaskCreateDialog from '@/components/task/TaskCreateDialog.vue'
import RequirementListView from '@/views/requirements/views/RequirementListView.vue'
import TaskListView from '@/views/tasks/views/TaskListView.vue'
import DefectListView from '@/views/defects/views/DefectListView.vue'
import PageLoading from '@/components/ui/PageLoading.vue'
// DefectViewDialog 已删除，待实现新组件
import { useRequirementsStore } from '@/stores/requirements'
import { useUserStore } from '@/stores/user'
import { versionAPI } from '@/api/version'
import { getRequirementById, updateRequirementAssignee } from '@/api/requirements'
import { assignTask } from '@/api/tasks'
import { updateDefectAssignee } from '@/api/defect'
import { getUsers } from '@/api/users'
import ResponseParser from '@/utils/responseParser'
import type {
  VersionOverviewItem,
  VersionWorkItemNode,
  VersionWorkItemsResponse,
  VersionStatus
} from '@/api/version'
// import type { UserOption } from '@/types/user'
import { ApiResponseHandler } from '@/types/api'
import { formatDate } from '@/utils/date'
import { useVersionStates } from '@/composables/useVersionStates'
import { useRequirementStates } from '@/composables/useRequirementStates'
import { useTaskStates } from '@/composables/useTaskStates'
import { useDefectStates } from '@/composables/useDefectStates'
import { useRequirementOptions } from '@/composables/useRequirementOptions'
import { useDefectOptions } from '@/composables/useDefectOptions'
import { usePermission } from '@/hooks/usePermission'
import { priorityApi } from '@/api/priority'
import { TASK_PRIORITIES } from '@/types/task'
import type { VersionTransitionRule, VersionCompletion } from '@/types/version'

type WorkItemType = 'requirement' | 'task' | 'defect'
type WorkItemFilterType = WorkItemType


const versionSearch = ref('')
const versions = ref<VersionOverviewItem[]>([])
const versionLoading = ref(false)
const selectedVersionId = ref<string>('')
const isCollapsed = ref(false)
const initialLoading = ref(true)
const isRefreshing = ref(false)

const workItems = ref<VersionWorkItemsResponse | null>(null)
const workItemsLoading = ref(false)
const activeType = ref<WorkItemFilterType>('requirement')
const statusFilter = ref<string | null>(null)
const keyword = ref('')
const tableMaxHeight = ref(600)

// 分页状态（每个类型独立）
const paginationState = reactive<Record<WorkItemType, { page: number; pageSize: number }>>({
  requirement: { page: 1, pageSize: 20 },
  task: { page: 1, pageSize: 20 },
  defect: { page: 1, pageSize: 20 }
})

// 选中项状态（每个类型独立）
const selectedIdsState = reactive<Record<WorkItemType, string[]>>({
  requirement: [],
  task: [],
  defect: []
})

// 动态组件映射
const listComponentMap = {
  requirement: RequirementListView,
  task: TaskListView,
  defect: DefectListView
}

// 当前激活的列表组件
const activeListComponent = computed(() => {
  return listComponentMap[activeType.value] || RequirementListView
})

// 当前激活列表的 props
const activeListProps = computed(() => {
  const items = getFilteredItemsByType(activeType.value)
  const pagination = paginationState[activeType.value]
  const selectedIds = selectedIdsState[activeType.value]
  
  const baseProps = {
    loading: workItemsLoading.value,
    pagination: {
      page: pagination.page,
      pageSize: pagination.pageSize,
      total: items.length
    },
    selectedIds,
    batchLoading: false
  }

  if (activeType.value === 'requirement') {
    return {
      ...baseProps,
      requirements: items as any[],
      statusOptions: requirementStatusOptions.value,
      priorityOptions: requirementPriorityOptions.value,
      users: userOptionsForList.value,
      statusOptionsForBatch: requirementStatusOptions.value,
      priorityOptionsForBatch: requirementPriorityOptions.value,
      usersForBatch: users.value
    }
  } else if (activeType.value === 'task') {
    return {
      ...baseProps,
      tasks: items as any[],
      statusOptions: taskStatusOptions.value,
      priorityOptions: taskPriorityOptionsForList.value,
      users: userOptionsForList.value,
      statusOptionsForBatch: taskStatusOptions.value,
      priorityOptionsForBatch: taskPriorityOptionsForList.value,
      usersForBatch: users.value
    }
  } else if (activeType.value === 'defect') {
    return {
      ...baseProps,
      defects: items as any[],
      statusOptions: defectStatusOptions.value,
      priorityOptions: defectPriorityOptionsForList.value,
      severityOptions: defectSeverityOptionsForList.value,
      typeOptions: defectTypeOptionsForList.value,
      users: userOptionsForList.value,
      statusOptionsForBatch: defectStatusOptions.value,
      priorityOptionsForBatch: defectPriorityOptionsForList.value,
      severityOptionsForBatch: defectSeverityOptionsForList.value,
      typeOptionsForBatch: defectTypeOptionsForList.value,
      usersForBatch: users.value
    }
  }
  
  return baseProps
})

// 根据类型获取过滤后的数据
const getFilteredItemsByType = (type: WorkItemType) => {
  if (!workItems.value) return []
  
  const { requirements = [], tasks = [], defects = [] } = workItems.value.items || {}
  let items: VersionWorkItemNode[] = []
  
  if (type === 'requirement') {
    items = requirements
  } else if (type === 'task') {
    items = tasks
  } else if (type === 'defect') {
    items = defects
  }
  
  // 应用状态筛选
  if (statusFilter.value) {
    items = items.filter(item => {
      const statusCode = (item.status || '').toString()
      return statusCode === statusFilter.value
    })
  }
  
  // 应用关键词筛选
  const keywordValue = keyword.value.trim().toLowerCase()
  if (keywordValue) {
    items = items.filter(item => {
      const searchFields = [
        item.title,
        item.assignee_name,
        item.meta?.requirement_title,
        item.meta?.task_title,
        item.meta?.defect_title
      ]
      return searchFields.some(field =>
        (field || '').toString().toLowerCase().includes(keywordValue)
      )
    })
  }
  
  // 排序
  items.sort((a, b) => {
    const getDateValue = (entry: VersionWorkItemNode) => {
      const primary = entry.associated_at || entry.meta?.updated_at || entry.meta?.created_at
      return primary ? new Date(primary).getTime() : 0
    }
    return getDateValue(b) - getDateValue(a)
  })
  
  // 转换为对应类型的数据格式
  return items.map(item => convertToListItem(item, type))
}

// 转换工作项为列表项格式
const convertToListItem = (item: VersionWorkItemNode, type: WorkItemType) => {
  const baseItem: any = {
    id: item.meta?.id || item.id,
    title: item.title,
    status: item.status,
    priority: item.priority,
    assignee_id: item.assignee_id || item.meta?.assignee_id,
    assignee_name: item.assignee_name || item.meta?.assignee_name || '',
    reporter_id: item.meta?.reporter_id,
    reporter_name: item.meta?.reporter_name || '',
    project_id: item.meta?.project_id,
    project_name: item.meta?.project_name || '',
    created_at: item.meta?.created_at || item.associated_at,
    updated_at: item.meta?.updated_at,
    start_date: item.meta?.start_date,
    due_date: item.meta?.due_date || item.meta?.found_date
  }
  
  if (type === 'requirement') {
    return {
      ...baseItem,
      requirement_type: item.meta?.requirement_type,
      source: item.meta?.source
    }
  } else if (type === 'task') {
    return {
      ...baseItem,
      task_type: item.meta?.task_type,
      requirement_id: item.meta?.requirement_id,
      requirement_title: item.meta?.requirement_title
    }
  } else if (type === 'defect') {
    return {
      ...baseItem,
      type: item.meta?.defect_type,
      severity: item.meta?.severity,
      found_date: item.meta?.found_date
    }
  }
  
  return baseItem
}

// 分配负责人相关
const assignDialogVisible = ref(false)
const assignLoading = ref(false)
const currentAssignItem = ref<VersionWorkItemNode | null>(null)
const selectedAssigneeId = ref<string>('')
const users = ref<Array<{ id: string; name: string; avatar?: string }>>([])

// 获取用户列表
const loadUsers = async () => {
  try {
    const response = await getUsers({ limit: 200})
    const parsed = ResponseParser.parseResponse(response)
    if (parsed.success && parsed.data) {
      const data = parsed.data as any
      users.value = data.items?.map((user: any) => ({
        id: user.id,
        name: user.name,
        avatar: user.avatar
      })) || []
    }
  } catch (error) {
    console.error('获取用户列表失败:', error)
  }
}

const router = useRouter()

const { loadStates: loadVersionStates, defaultState } = useVersionStates()


const allowedTransitionsMap = reactive<Record<string, VersionTransitionRule[]>>({})
const transitionLoadingMap = reactive<Record<string, boolean>>({})
const completionDataMap = reactive<Record<string, VersionCompletion | null>>({})

const transitionDialogVisible = ref(false)
const currentTransition = ref<VersionTransitionRule | null>(null)
const currentTransitionVersionId = ref('')

const detailDialogVisible = ref(false)
const editDialogVisible = ref(false)
const currentVersionId = ref('')

// 详情对话框状态
const requirementsStore = useRequirementsStore()
const userStore = useUserStore()
const taskViewDialogVisible = ref(false)
const defectViewDialogVisible = ref(false)
const selectedTaskId = ref('')
const selectedDefectId = ref('')
const currentUserId = computed(() => {
  return userStore.userInfo?.id || ''
})

const { hasPermission } = usePermission()
const canTransition = computed(() => hasPermission('version:transition_request') || hasPermission('version:update'))
const canEdit = computed(() => hasPermission('version:update'))
const canDelete = computed(() => hasPermission('version:delete'))
const currentCompletionData = computed(() => {
  if (!currentTransitionVersionId.value) {
    return null
  }
  return completionDataMap[currentTransitionVersionId.value] ?? null
})

const {
  statusOptions: requirementStatusOptions,
  loadStates: loadRequirementStates
} = useRequirementStates()

const {
  statusOptions: taskStatusOptions,
  loadStates: loadTaskStates
} = useTaskStates()

const {
  statusOptions: defectStatusOptions,
  loadStates: loadDefectStates
} = useDefectStates()

const {
  loadOptions: loadRequirementOptions,
  priorityOptions: requirementPriorityOptionsRaw
} = useRequirementOptions()

const {
  loadOptions: loadDefectOptions,
  formattedPriorityOptions: defectPriorityOptionsRaw,
  formattedSeverityOptions: defectSeverityOptionsRaw
} = useDefectOptions()

// 任务优先级选项
const taskPriorityOptions = ref<Array<{ code: string; name: string }>>([])

// 加载任务优先级选项
const loadTaskPriorityOptions = async () => {
  try {
    const response = await priorityApi.getAll('task')
    if (response?.data?.success && Array.isArray(response.data.data)) {
      taskPriorityOptions.value = response.data.data.map((p: any) => ({
        code: p.code || p.value,
        name: p.name || p.label
      }))
    } else {
      // 使用默认选项
      taskPriorityOptions.value = TASK_PRIORITIES.map(p => ({
        code: p.value,
        name: p.label
      }))
    }
  } catch (error) {
    console.error('加载任务优先级选项失败:', error)
    // 使用默认选项
    taskPriorityOptions.value = TASK_PRIORITIES.map(p => ({
      code: p.value,
      name: p.label
    }))
  }
}


// 需求优先级选项（列表格式）
const requirementPriorityOptions = computed(() => {
  return requirementPriorityOptionsRaw.value.map(p => ({
    value: p.value,
    label: p.label
  }))
})

// 任务优先级选项（列表格式）
const taskPriorityOptionsForList = computed(() => {
  return taskPriorityOptions.value.map(p => ({
    value: p.code,
    label: p.name
  }))
})

// 缺陷优先级选项（列表格式）
const defectPriorityOptionsForList = computed(() => {
  return defectPriorityOptionsRaw.value.map(p => ({
    value: p.value,
    label: p.label
  }))
})

// 缺陷严重程度选项（列表格式）
const defectSeverityOptionsForList = computed(() => {
  return defectSeverityOptionsRaw.value.map(s => ({
    value: s.value,
    label: s.label
  }))
})

// 缺陷类型选项（列表格式）
const defectTypeOptionsForList = computed(() => {
  // 缺陷类型是固定的，从类型定义中获取
  return [
    { value: 'bug', label: '缺陷' },
    { value: 'feature', label: '功能' },
    { value: 'improvement', label: '改进' },
    { value: 'task', label: '任务' }
  ]
})

// 用户选项（列表格式，包含头像）
const userOptionsForList = computed(() => {
  return users.value.map(user => ({
    id: user.id,
    name: user.name,
    avatar: user.avatar
  }))
})

const filteredVersions = computed(() => {
  const keywordValue = versionSearch.value.trim().toLowerCase()
  if (!keywordValue) {
    return versions.value
  }
  return versions.value.filter(item => {
    const fields = [
      item.name,
      item.version_number,
      item.project_name
    ]
    return fields.some(field =>
      (field || '').toString().toLowerCase().includes(keywordValue)
    )
  })
})

const selectedVersion = computed(() => {
  return versions.value.find(item => item.id === selectedVersionId.value) || null
})

// 将版本列表转换为版本选项格式，用于需求详情页
const versionOptions = computed(() => {
  return versions.value.map(version => ({
    id: version.id,
    name: version.name,
    version_number: version.version_number,
    status: version.status,
    project_id: version.project_id,
    projectName: version.project_name
  }))
})

const versionDetail = computed(() => {
  if (workItems.value?.version) {
    return workItems.value.version
  }
  return selectedVersion.value
})

const workItemCounts = computed(() => {
  const requirements = workItems.value?.items?.requirements?.length ?? 0
  const tasks = workItems.value?.items?.tasks?.length ?? 0
  const defects = workItems.value?.items?.defects?.length ?? 0
  return {
    requirement: requirements,
    task: tasks,
    defect: defects,
    all: requirements + tasks + defects
  }
})


const typeMetaMap: Record<
  WorkItemType,
  { label: string; tagType: 'primary' | 'success' | 'danger'; relationPrefix: string }
> = {
  requirement: { label: '需求', tagType: 'primary', relationPrefix: '需求' },
  task: { label: '任务', tagType: 'success', relationPrefix: '任务' },
  defect: { label: '缺陷', tagType: 'danger', relationPrefix: '缺陷' }
}



function normalizePercent(value?: number | null): number {
  if (!value || Number.isNaN(value)) return 0
  return Math.max(0, Math.min(100, Number(value.toFixed(2))))
}

function calcPercent(stats?: { total?: number | null; completed?: number | null }): number {
  if (!stats || !stats.total || stats.total <= 0) {
    return 0
  }
  const percent = ((stats.completed ?? 0) / stats.total) * 100
  if (!Number.isFinite(percent)) {
    return 0
  }
  return normalizePercent(percent)
}

function calcOverallPercent(version: VersionOverviewItem): number {
  const statsList = [
    version.requirement_stats,
    version.task_stats,
    version.defect_stats
  ]

  let total = 0
  let completed = 0

  statsList.forEach(stats => {
    if (!stats || !stats.total || stats.total <= 0) return
    total += stats.total
    completed += stats.completed ?? 0
  })

  if (total <= 0) {
    return normalizePercent(version.progress ?? 0)
  }

  return normalizePercent((completed / total) * 100)
}

function formatPlannedDate(date?: string | null): string {
  return date ? formatDate(date, 'YYYY-MM-DD') : ''
}

function castVersionStatus(status?: string | null): VersionStatus {
  // 从状态管理系统获取默认状态，如果没有状态则返回空字符串
  return (status as VersionStatus) || (defaultState.value?.code || '')
}


async function loadVersions(isRefresh = false) {
  if (isRefresh) {
    isRefreshing.value = true
    initialLoading.value = true
  }
  versionLoading.value = true
  try {
    const response = await versionAPI.getVersionsOverview({ limit: 200 })
    const payload = ApiResponseHandler.safeExtractData(response, {
      items: [],
      total: 0
    })
    versions.value = payload.items || []

    if (!versions.value.length) {
      selectedVersionId.value = ''
      workItems.value = null
      return
    }

    // 保留当前选择，若不存在则选择首个
    const exists = versions.value.some(item => item.id === selectedVersionId.value)
    if (!exists) {
      selectedVersionId.value = versions.value[0].id
    }
  } catch (error) {
    console.error('获取版本总览失败', error)
    ElMessage.error('获取版本总览失败，请稍后重试')
  } finally {
    versionLoading.value = false
    if (isRefresh) {
      setTimeout(() => {
        initialLoading.value = false
        isRefreshing.value = false
      }, 300)
    } else if (initialLoading.value) {
      initialLoading.value = false
    }
  }
}

const goToPlanning = () => {
  router.push({ name: 'VersionsPlanning' })
}
async function loadWorkItems(versionId: string) {
  if (!versionId) {
    workItems.value = null
    return
  }

  workItemsLoading.value = true
  try {
    const response = await versionAPI.getVersionWorkItems(versionId)
    workItems.value = ApiResponseHandler.extractData(response)
  } catch (error) {
    console.error('获取版本工作项失败', error)
    ElMessage.error('获取版本详情失败，请稍后重试')
    workItems.value = null
  } finally {
    workItemsLoading.value = false
  }
}

function handleSelectVersion(versionId: string) {
  if (selectedVersionId.value === versionId) {
    return
  }
  selectedVersionId.value = versionId
}

// 任务拆分相关状态
const taskSplitDialogVisible = ref(false)
const taskSplitItem = ref<{ type: WorkItemType; id: string; projectId: string; title: string } | null>(null)

// 打开任务拆分对话框
const openTaskSplit = async (item: any) => {
  const itemId = item.id
  if (!itemId) {
    ElMessage.warning('无法识别工作项信息')
    return
  }
  
  try {
    let projectId = item.project_id || ''
    let title = item.title || ''
    
    // 如果是需求，获取详情以获取项目ID
    if (activeType.value === 'requirement') {
      const response = await getRequirementById(itemId)
      if (response && response.success && response.data) {
        projectId = response.data.project_id || ''
        title = response.data.title || title
      }
    }
    
    taskSplitItem.value = {
      type: activeType.value,
      id: itemId,
      projectId,
      title
    }
    taskSplitDialogVisible.value = true
  } catch (error) {
    console.error('获取工作项信息失败:', error)
    ElMessage.error('获取工作项信息失败，请稍后重试')
  }
}

// 处理任务拆分事件
const handleSplitTask = (item: any) => {
  openTaskSplit(item)
}

const viewRequirement = async (requirement: VersionWorkItemNode) => {
  const requirementId = requirement.meta?.id || requirement.id
  if (!requirementId) {
    ElMessage.warning('无法识别需求信息')
    return
  }
  // 使用需求 store 打开详情面板（会自动加载数据）
  await requirementsStore.openDetailPanel(requirementId)
}

const viewTask = (task: VersionWorkItemNode) => {
  const taskId = task.meta?.id || task.id
  if (!taskId) {
    ElMessage.warning('无法识别任务信息')
    return
  }
  selectedTaskId.value = taskId
  taskViewDialogVisible.value = true
}

const viewDefect = (defect: VersionWorkItemNode) => {
  const defectId = defect.meta?.id || defect.id
  if (!defectId) {
    ElMessage.warning('无法识别缺陷信息')
    return
  }
  selectedDefectId.value = defectId
  defectViewDialogVisible.value = true
}


const handleRequirementDetailVisibleChange = (visible: boolean) => {
  if (!visible) {
    requirementsStore.closeDetailPanel()
  }
}


// 确认分配
const confirmAssign = async () => {
  if (!currentAssignItem.value) return
  
  assignLoading.value = true
  try {
    let response: any
    const assigneeId = selectedAssigneeId.value || null
    
    if (currentAssignItem.value.type === 'requirement') {
      const requirementId = currentAssignItem.value.meta?.id || currentAssignItem.value.id
      response = await updateRequirementAssignee(requirementId, { assignee_id: assigneeId })
    } else if (currentAssignItem.value.type === 'task') {
      const taskId = currentAssignItem.value.meta?.id || currentAssignItem.value.id
      response = await assignTask(taskId, assigneeId || '')
    } else if (currentAssignItem.value.type === 'defect') {
      const defectId = currentAssignItem.value.meta?.id || currentAssignItem.value.id
      response = await updateDefectAssignee(defectId, assigneeId || undefined)
    } else {
      ElMessage.error('不支持的工作项类型')
      return
    }
    
    const parsed = ResponseParser.parseResponse(response)
    if (parsed.success) {
      ElMessage.success('分配成功')
      assignDialogVisible.value = false
      currentAssignItem.value = null
      selectedAssigneeId.value = ''
      
      // 刷新工作项列表
      if (selectedVersionId.value) {
        await loadWorkItems(selectedVersionId.value)
      }
    } else {
      ElMessage.error(parsed.message || '分配失败')
    }
  } catch (error) {
    console.error('分配失败:', error)
    const errorMessage = ResponseParser.extractMessage(error) || '分配失败'
    ElMessage.error(errorMessage)
  } finally {
    assignLoading.value = false
  }
}

// 事件处理函数
const handleOpenDetail = (id: string) => {
  if (activeType.value === 'requirement') {
    viewRequirement({ id, meta: { id }, type: 'requirement', title: '' } as VersionWorkItemNode)
  } else if (activeType.value === 'task') {
    viewTask({ id, meta: { id }, type: 'task', title: '' } as VersionWorkItemNode)
  } else if (activeType.value === 'defect') {
    viewDefect({ id, meta: { id }, type: 'defect', title: '' } as VersionWorkItemNode)
  }
}

const handleUpdateStatus = (id: string, status: string) => {
  // TODO: 实现状态更新逻辑
  console.log('Update status:', id, status)
}

const handleUpdatePriority = (id: string, priority: string) => {
  // TODO: 实现优先级更新逻辑
  console.log('Update priority:', id, priority)
}

const handleUpdateSeverity = (id: string, severity: string) => {
  // TODO: 实现严重程度更新逻辑
  console.log('Update severity:', id, severity)
}

const handleUpdateAssignee = (id: string, assigneeId: string | null) => {
  // TODO: 实现负责人更新逻辑
  console.log('Update assignee:', id, assigneeId)
}

const handleDelete = async (id: string) => {
  // TODO: 实现删除逻辑
  console.log('Delete:', id)
  // 刷新工作项列表
  if (selectedVersionId.value) {
    await loadWorkItems(selectedVersionId.value)
  }
}

const handleRefresh = async () => {
  if (selectedVersionId.value) {
    await loadWorkItems(selectedVersionId.value)
  }
}

const handlePageChange = (page: number) => {
  paginationState[activeType.value].page = page
}

const handlePageSizeChange = (size: number) => {
  paginationState[activeType.value].pageSize = size
  paginationState[activeType.value].page = 1
}

const handleSelectChange = (ids: string[]) => {
  selectedIdsState[activeType.value] = ids
}

// 监听类型切换，重置分页
watch(activeType, () => {
  paginationState[activeType.value].page = 1
})

const handleTaskCreated = async () => {
  // 重置状态
  taskSplitItem.value = null
  taskSplitDialogVisible.value = false
  
  // 刷新工作项列表
  if (selectedVersionId.value) {
    await loadWorkItems(selectedVersionId.value)
  }
}


async function refreshVersions() {
  try {
    await loadVersions(true)
    if (selectedVersionId.value) {
      await loadWorkItems(selectedVersionId.value)
    }
    ElMessage.success('刷新成功')
  } catch (error) {
    console.error('刷新失败:', error)
    ElMessage.error('刷新失败，请稍后重试')
  }
}

async function loadVersionTransitionData(versionId: string, force = false) {
  if (!versionId) return
  if (!force && allowedTransitionsMap[versionId]) {
    return
  }
  transitionLoadingMap[versionId] = true
  try {
    const [transitionsResponse, completion] = await Promise.all([
      versionAPI.getAllowedTransitions(versionId),
      versionAPI.getCompletion(versionId)
    ])
    allowedTransitionsMap[versionId] = transitionsResponse.allowed_transitions || []
    completionDataMap[versionId] = completion ?? null
  } catch (error) {
    console.error('加载状态流转数据失败:', error)
    ElMessage.error('获取状态流转数据失败，请稍后重试')
  } finally {
    transitionLoadingMap[versionId] = false
  }
}

const openTransitionDialog = async (versionId: string, transition: VersionTransitionRule) => {
  if (!transition) return
  currentTransitionVersionId.value = versionId
  currentTransition.value = transition
  if (!completionDataMap[versionId]) {
    await loadVersionTransitionData(versionId, true)
  }
  transitionDialogVisible.value = true
}

const handleTransitionSuccess = async () => {
  transitionDialogVisible.value = false
  const versionId = currentTransitionVersionId.value
  if (versionId) {
    await Promise.all([loadWorkItems(versionId), loadVersionTransitionData(versionId, true)])
  }
  await loadVersions()
}

const handleViewVersion = (versionId: string) => {
  currentVersionId.value = versionId
  detailDialogVisible.value = true
}

const handleEditVersion = (versionId: string) => {
  currentVersionId.value = versionId
  editDialogVisible.value = true
}

const handleEditFromDetail = (version: any) => {
  detailDialogVisible.value = false
  currentVersionId.value = version.id
  editDialogVisible.value = true
}

const handleVersionUpdated = async () => {
  // 刷新版本列表
  await loadVersions()
  // 如果当前选中的版本被更新，重新加载工作项
  if (currentVersionId.value === selectedVersionId.value) {
    await loadWorkItems(selectedVersionId.value)
  }
  editDialogVisible.value = false
  currentVersionId.value = ''
}

const handleTogglePin = async (version: VersionOverviewItem) => {
  try {
    const newPinnedStatus = !version.is_pinned
    const response = await versionAPI.updateVersion(version.id, {
      is_pinned: newPinnedStatus
    })
    
    if (response.success) {
      ElMessage.success(newPinnedStatus ? '置顶成功' : '取消置顶成功')
      // 刷新版本列表
      await loadVersions()
    } else {
      ElMessage.error(response.message || '操作失败')
    }
  } catch (error) {
    console.error('置顶操作失败:', error)
    ElMessage.error('操作失败，请稍后重试')
  }
}

const handleDeleteVersion = async (version: VersionOverviewItem) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除版本"${version.name}"吗？此操作不可恢复，将同时删除该版本的所有关联数据。`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    const response = await versionAPI.deleteVersion(version.id)
    
    if (response.success) {
      ElMessage.success(response.message || '删除版本成功')
      
      // 如果删除的是当前选中的版本，清空选中状态
      if (version.id === selectedVersionId.value) {
        selectedVersionId.value = ''
        workItems.value = null
      }
      
      // 刷新版本列表
      await loadVersions()
    } else {
      ElMessage.error(response.message || '删除版本失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除版本失败:', error)
      ElMessage.error('删除版本失败，请稍后重试')
    }
  }
}

watch(selectedVersionId, async (newVal) => {
  statusFilter.value = null
  keyword.value = ''
  activeType.value = 'requirement'
  if (newVal) {
    await Promise.all([loadWorkItems(newVal), loadVersionTransitionData(newVal, true)])
  } else {
    workItems.value = null
  }
})

watch(activeType, () => {
  statusFilter.value = null
})

const calculateTableHeight = () => {
  nextTick(() => {
    // 计算表格可用高度
    // 主面板高度 - 头部高度 - 内容区域padding - 工作项卡片头部高度 - 间距
    const mainPanelHeight = window.innerHeight - 32 - 32 // 减去页面padding
    const headerHeight = 120 // 主头部高度
    const contentPadding = 32 // 内容区域padding
    const workItemsHeaderHeight = 60 // 工作项卡片头部高度
    const gaps = 48 // 各种间距
    const calculatedHeight = mainPanelHeight - headerHeight - contentPadding - workItemsHeaderHeight - gaps
    tableMaxHeight.value = Math.max(400, calculatedHeight) // 最小高度400px
  })
}

onMounted(async () => {
  calculateTableHeight()
  window.addEventListener('resize', calculateTableHeight)
  await Promise.allSettled([
    loadVersionStates(),
    loadRequirementStates(),
    loadTaskStates(),
    loadDefectStates(),
    loadRequirementOptions(),
    loadDefectOptions(),
    loadTaskPriorityOptions(),
    loadUsers()
  ])
  await loadVersions()
  
  // 从路由参数获取版本ID
  const versionId = router.currentRoute.value.query.version_id as string
  if (versionId) {
    selectedVersionId.value = versionId
    await Promise.all([loadWorkItems(versionId), loadVersionTransitionData(versionId, true)])
  }
  
  initialLoading.value = false
})

onUnmounted(() => {
  window.removeEventListener('resize', calculateTableHeight)
})

// 切换收拢/展开状态（只控制左侧版本列表）
const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value
  // 在下一个tick重新计算表格高度，以适应布局变化
  nextTick(() => {
    calculateTableHeight()
  })
}
</script>

<style scoped>
.version-management-page {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 16px;
  box-sizing: border-box;
}

.page-wrapper {
  display: flex;
  gap: 16px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.sidebar {
  display: flex;
  flex-direction: column;
  width: 300px;
  position: relative;
  transition: width 0.24s ease, transform 0.24s ease;
  flex-shrink: 0;
  max-width: 400px;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

.sidebar.is-collapsed {
  width: 60px;
  transform: translateX(-12px);
}

.sidebar.is-collapsed .sidebar-content {
  display: none;
}

.sidebar.is-collapsed .sidebar-header {
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 8px;
}

.sidebar.is-collapsed .sidebar-header h3 {
  writing-mode: vertical-rl;
  margin: 0;
  letter-spacing: 4px;
}

.sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #ffffff;
  border-radius: 16px;
  box-shadow: 0 10px 24px rgba(33, 51, 96, 0.06);
  margin-bottom: 12px;
  flex-shrink: 0;
}

.sidebar-header h3 {
  margin: 0;
  font-size: 15px;
  color: #2b3c5c;
  font-weight: 600;
}

.collapse-btn {
  color: #4b5e89;
  transition: color 0.2s ease;
}

.collapse-btn:hover {
  color: #409eff;
}

.sidebar-content {
  background: #ffffff;
  border-radius: 16px;
  box-shadow: 0 10px 24px rgba(33, 51, 96, 0.06);
  padding: 16px 18px;
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
  min-height: 0;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sidebar-content::-webkit-scrollbar {
  width: 6px;
}

.sidebar-content::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.sidebar-content::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.sidebar-content::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.version-search-input {
  flex-shrink: 0;
}

.version-list-wrapper {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.version-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-bottom: 8px;
}

.version-card {
  padding: 16px;
  background: #ffffff;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.version-card:hover {
  border-color: #409eff;
  box-shadow: 0 2px 12px rgba(64, 158, 255, 0.1);
  transform: translateY(-1px);
}

.version-card.is-active {
  border-color: #409eff;
  background: #f0f9ff;
  box-shadow: 0 2px 12px rgba(64, 158, 255, 0.15);
}

.version-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.version-name-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.version-name {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #1f2d3d;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

.pinned-icon {
  color: #e6a23c;
  font-size: 16px;
  flex-shrink: 0;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.status-trigger {
  display: flex;
  align-items: center;
}

.status-dropdown {
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.status-dropdown:hover {
  background-color: #f5f7fa;
}

.status-dropdown-icon {
  font-size: 12px;
  color: #909399;
}

.action-button {
  color: #606266;
  transition: color 0.2s ease;
}

.action-button:hover {
  color: #409eff;
}

.version-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  font-size: 13px;
  color: #606266;
  flex-wrap: wrap;
}

.version-number {
  font-weight: 500;
  color: #606266;
}

.project-name {
  color: #909399;
}

.version-stats {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}

.stat-label {
  color: #909399;
}

.stat-value {
  color: #606266;
  font-weight: 500;
}

.overall-progress {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}

.overall-label {
  font-size: 13px;
  color: #606266;
  white-space: nowrap;
  flex-shrink: 0;
}

.overall-progress-bar {
  flex: 1;
  min-width: 0;
}

.overall-percent {
  font-size: 13px;
  color: #67c23a;
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
}

.overall-detail {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 12px;
  color: #909399;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.version-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 12px;
  border-top: 1px solid #f0f0f0;
  font-size: 13px;
}

.footer-label {
  color: #909399;
}

.footer-value {
  color: #606266;
  font-weight: 500;
}

.main-panel {
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border-radius: 8px;
  border: 1px solid #e4e7ed;
  overflow: hidden;
  flex: 1;
  min-width: 0;
  min-height: 0;
  height: 100%;
}

.main-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 24px;
  background: #fafafa;
  border-bottom: 1px solid #e4e7ed;
  flex-shrink: 0;
  flex-wrap: wrap;
}

.main-title {
  flex: 1;
  min-width: 0;
}

.title-text {
  margin: 0 0 12px 0;
  font-size: 20px;
  font-weight: 600;
  color: #1f2d3d;
}

.title-tags {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.title-meta-item {
  position: relative;
  padding-left: 12px;
  font-size: 13px;
  color: #606266;
}

.title-meta-item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 12px;
  background-color: #dcdfe6;
}

/* 第一个元数据项（紧跟在标签后面）不需要分隔线 */
.el-tag + .title-meta-item,
.title-tags > .title-meta-item:first-of-type {
  padding-left: 0;
}

.el-tag + .title-meta-item::before,
.title-tags > .title-meta-item:first-of-type::before {
  display: none;
}

.main-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.version-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 20px 24px;
  box-sizing: border-box;
}

.work-items-card {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: hidden;
  width: 100%;
  box-sizing: border-box;
}

.placeholder-action {
  color: #c0c4cc;
  font-size: 12px;
}

.work-items-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  flex-wrap: wrap;
  padding: 0 4px;
}

.tabs-wrapper {
  flex: 1;
  min-width: 0;
}

.work-item-tabs {
  :deep(.el-tabs__header) {
    margin: 0;
    border-bottom: 2px solid #e4e7ed;
  }

  :deep(.el-tabs__nav-wrap) {
    &::after {
      display: none;
    }
  }

  :deep(.el-tabs__item) {
    padding: 0 24px;
    height: 48px;
    line-height: 48px;
    font-size: 14px;
    font-weight: 500;
    color: #606266;
    border: none;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    position: relative;

    &:hover {
      color: #409eff;
    }

    &.is-active {
      color: #409eff;
      font-weight: 600;

      &::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 2px;
        background: linear-gradient(90deg, #409eff 0%, #66b1ff 100%);
        border-radius: 2px 2px 0 0;
      }
    }
  }

  :deep(.el-tabs__active-bar) {
    display: none;
  }
}

.tab-label {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tab-name {
  font-size: 14px;
  font-weight: inherit;
}

.tab-badge {
  :deep(.el-badge__content) {
    background-color: #909399;
    border-color: #909399;
    font-size: 11px;
    height: 18px;
    line-height: 18px;
    padding: 0 6px;
    min-width: 18px;
    border-radius: 9px;
  }
}

.work-item-tabs :deep(.el-tabs__item.is-active .tab-badge) {
  :deep(.el-badge__content) {
    background-color: #409eff;
    border-color: #409eff;
  }
}

.work-items-content {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  width: 100%;
  box-sizing: border-box;
}

.fade-slide-enter-active,
.fade-slide-leave-active {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.fade-slide-enter-from {
  opacity: 0;
  transform: translateX(10px);
}

.fade-slide-leave-to {
  opacity: 0;
  transform: translateX(-10px);
}

.work-items-filters {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.status-option {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
}

.status-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #909399;
}

.item-title {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #1f2d3d;
  font-weight: 500;
  min-width: 0;
  flex-wrap: wrap;
}

.item-name {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.item-name.clickable {
  color: #409eff;
  cursor: pointer;
  transition: color 0.2s ease;
}

.item-name.clickable:hover {
  color: #66b1ff;
  text-decoration: underline;
}

.relation-tag {
  background-color: #ecf5ff;
  color: #409eff;
}

.item-meta {
  display: flex;
  gap: 16px;
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
  flex-wrap: wrap;
  min-width: 0;
}

.item-meta span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.status-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.status-cell span:last-child {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.assignee-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.assignee-cell:hover {
  background-color: #f5f7fa;
}

.assignee-avatar {
  flex-shrink: 0;
}

.assignee-avatar.unassigned {
  background-color: #e4e7ed;
  color: #909399;
}

.assignee-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #606266;
}

.assignee-name.unassigned {
  color: #c0c4cc;
}

.assign-icon {
  font-size: 14px;
  color: #909399;
  opacity: 0;
  transition: opacity 0.2s ease;
  flex-shrink: 0;
}

.assignee-cell:hover .assign-icon {
  opacity: 1;
}

.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  padding: 16px 0;
  border-top: 1px solid #ebeef5;
  margin-top: 16px;
}

/* 表格样式优化 */
:deep(.el-table) {
  font-size: 13px;
  width: 100%;
  max-width: 100%;
}

:deep(.el-table__body-wrapper) {
  max-height: 100%;
  overflow-y: auto;
}

:deep(.el-table__header-wrapper),
:deep(.el-table__body-wrapper) {
  width: 100%;
  overflow-x: auto;
}

:deep(.el-table th) {
  background-color: #fafafa;
  color: #606266;
  font-weight: 600;
  padding: 12px 0;
}

:deep(.el-table td) {
  padding: 12px 0;
}

:deep(.el-table .cell) {
  padding: 0 12px;
  word-break: break-word;
  line-height: 1.5;
}

:deep(.el-table--border) {
  border: 1px solid #ebeef5;
}

:deep(.el-table--border th),
:deep(.el-table--border td) {
  border-right: 1px solid #ebeef5;
}

:deep(.el-table--stripe .el-table__body tr.el-table__row--striped td) {
  background-color: #fafafa;
}

:deep(.el-table--stripe .el-table__body tr.el-table__row--striped:hover td) {
  background-color: #f5f7fa;
}

:deep(.el-table__body tr:hover > td) {
  background-color: #f5f7fa;
}

@media (max-width: 1440px) {
  .version-management-page {
    padding: 12px;
  }
  
  .page-wrapper {
    gap: 12px;
  }
  
  .sidebar {
    width: 280px;
  }
  
  .sidebar.is-collapsed {
    width: 60px;
  }
  
  .version-content {
    padding: 16px 20px;
  }
  
  .main-header {
    padding: 16px 20px;
  }
  
  .item-name {
    max-width: 280px;
  }
}

@media (max-width: 1280px) {
  .version-management-page {
    padding: 12px;
  }
  
  .page-wrapper {
    flex-direction: column;
    gap: 12px;
  }
  
  .sidebar {
    width: 100%;
    height: auto;
    max-height: 400px;
  }

  .sidebar.is-collapsed {
    width: 100%;
    transform: none;
    max-height: 60px;
  }
  
  .sidebar.is-collapsed .sidebar-header {
    flex-direction: row;
    justify-content: space-between;
    padding: 12px 16px;
  }
  
  .sidebar.is-collapsed .sidebar-header h3 {
    writing-mode: horizontal-tb;
    letter-spacing: normal;
    font-size: 14px;
  }

  .main-panel {
    flex: 1;
    min-height: 400px;
    height: auto;
  }
  
  .version-content {
    padding: 16px;
  }
  
  .main-header {
    padding: 16px;
  }
}

/* 响应式优化 */
@media (max-width: 768px) {
  .version-management-page {
    padding: 8px;
  }
  
  .page-wrapper {
    gap: 8px;
  }
  
  .sidebar {
    border-radius: 6px;
  }
  
  .sidebar-header {
    padding: 12px 16px;
  }
  
  .sidebar-header h3 {
    font-size: 14px;
  }
  
  .sidebar-content {
    padding: 12px;
    gap: 8px;
  }
  
  .version-card {
    padding: 12px;
  }
  
  .version-name {
    font-size: 14px;
  }
  
  .main-header {
    padding: 16px;
    gap: 12px;
  }
  
  .title-text {
    font-size: 18px;
    margin-bottom: 8px;
  }
  
  .title-tags {
    gap: 8px;
  }
  
  .title-meta-item {
    font-size: 12px;
    padding-left: 8px;
  }
  
  .main-actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }
  
  .main-actions .el-button {
    width: 100%;
  }
  
  .version-content {
    padding: 12px;
    gap: 12px;
  }
  
  .main-header {
    padding: 12px;
    gap: 12px;
  }
  
  .work-items-card {
    gap: 8px;
  }
  
  .work-items-header {
    padding: 0 2px;
  }
}

/* 优化动画性能 */
.sidebar {
  will-change: width, transform;
}
</style>

